package com.example.springboottestgit.service;

import com.alibaba.fastjson.JSONObject;
import com.example.springboottestgit.bean.BusinessException;
import com.example.springboottestgit.bean.CommonException;
import com.example.springboottestgit.bean.vo.InputVO;
import com.example.springboottestgit.enums.ExceptionCodeEnum;
import com.example.springboottestgit.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @author: ZZZ
 */
@Slf4j
@Service
public class FileService {
    @Value("${invite.tender.upload.path}")
    private String inviteTenderUploadPath;
    @Value("${invite.tender.analysis.path}")
    private String inviteTenderAnalysisPath;
    @Value("${invite.tender.exe.script.path}")
    private String inviteTenderExeScriptPath;


    @Value("${submit.tender.upload.path}")
    private String submitTenderUploadPath;
    @Value("${submit.tender.analysis.path}")
    private String submitTenderAnalysisPath;
    @Value("${submit.tender.exe.script.path}")
    private String submitTenderExeScriptPath;

    @Value("${intelligent.match.mode.onload.url}")
    private String modeOnloadUrl;


    @Autowired
    private InviteTenderService inviteTenderService;

    @Autowired
    private SubmitTenderService submitTenderService;

    public List<Long> inviteTenderUpload(List<MultipartFile> list) {
        List<Long> ids = new ArrayList<>();
        for (MultipartFile file : list) {
            //if (file.isEmpty()) {
            //return "上传失败，请选择文件";
            //}
            // 获取文件名 xxx.doc
            String fileName = file.getOriginalFilename().replace(" ", "");
            // xxx
            String prefixName = fileName.substring(0, fileName.lastIndexOf("."));
            // 获取文件的后缀名  .doc
            String suffixName = fileName.substring(fileName.lastIndexOf("."));

            // 上传后的路径
            String filePath = inviteTenderUploadPath;

            // 解决中文问题，liunx下中文路径，图片显示问题

            //fileName = UUID.randomUUID() + suffixName;
            long timestamp = System.currentTimeMillis();

            String newFileName = prefixName + "-" + timestamp + suffixName;

            // 构建上传路径
            File dest = new File(filePath + fileName);

            // 检测是否存在目录
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
            try {
                // 保存文件
                log.info("========招标文件上传==========");
                file.transferTo(dest);
                inviteTenderService.save(timestamp, fileName);
                ids.add(timestamp);
                //执行解析脚本
                log.info("========执行招标文件解析命令==========");
                exeScript(inviteTenderExeScriptPath, filePath + fileName, inviteTenderAnalysisPath);

                log.info("========招标读取解析文件==========");
                String analysisPath = inviteTenderAnalysisPath + prefixName + "_law.json";
                log.info("文件路径：" + analysisPath);
                String jsonStr = tenderAnalysis(analysisPath);
                inviteTenderService.question(timestamp, jsonStr);
            } catch (Exception e) {
                if (e instanceof CommonException) {
                    CommonException commonException = (CommonException) e;
                    throw commonException;
                }
                log.error("招标文件上传失败", e);
                inviteTenderService.updateStatus(timestamp, 2);
                throw new BusinessException(ExceptionCodeEnum.BUSINESS_ERROR.code, "招标文件上传失败");
            }
        }
        return ids;
    }


    public void submitTenderUpload(List<MultipartFile> list, Long id) {

        //List<Long> ids = new ArrayList<>();
        for (MultipartFile file : list) {
            //if (file.isEmpty()) {
            //return "上传失败，请选择文件";
            //}
            // 获取文件名 xxx.doc
            String fileName = file.getOriginalFilename().replace(" ", "");
            // xxx
            String prefixName = fileName.substring(0, fileName.lastIndexOf("."));
            // 获取文件的后缀名  .doc
            String suffixName = fileName.substring(fileName.lastIndexOf("."));

            // 上传后的路径
            String filePath = submitTenderUploadPath;

            // 解决中文问题，liunx下中文路径，图片显示问题

            //fileName = UUID.randomUUID() + suffixName;
            long id2 = System.currentTimeMillis();

            //String newFileName = prefixName + "-" + timestamp + suffixName;

            // 构建上传路径
            File dest = new File(filePath + fileName);

            // 检测是否存在目录
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
            try {

                // 保存文件
                log.info("========投标文件上传==========");
                file.transferTo(dest);
                submitTenderService.save(id, id2, fileName);



                //执行解析脚本
                log.info("========执行投标文件解析命令==========");
                exeScript(submitTenderExeScriptPath, filePath + fileName, submitTenderAnalysisPath);


                // 重新加载模型
                log.info("========重新加载模型==========");
                startModel(prefixName + "_toubiao");
                log.info("检索文件名：" + prefixName + "_toubiao");



                log.info("========读取招标解析文件==========");
                String inviteTenderName = inviteTenderService.inviteTenderName(id);
                String analysisPath = inviteTenderAnalysisPath + inviteTenderName + "_result.txt";
                log.info("文件路径：" + analysisPath);
                String jsonStr = tenderAnalysis(analysisPath);
                submitTenderService.question(id, id2, jsonStr);
            } catch (Exception e) {
                if (e instanceof CommonException) {
                    CommonException commonException = (CommonException) e;
                    throw commonException;
                }
                log.error("投标文件上传失败", e);
                submitTenderService.updateStatus(id, id2, 2);
                //throw new BusinessException("001001", "投标文件上传失败: " + e.getMessage());
                throw new BusinessException(ExceptionCodeEnum.BUSINESS_ERROR.code, "投标文件上传失败");
            }
        }
    }

    public String tenderAnalysis(String path) {
        String jsonStr = "";
        try {
            FileReader reader = new FileReader(path);
            BufferedReader bufferedReader = new BufferedReader(reader);
            StringBuilder stringBuilder = new StringBuilder();
            String line;

            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line);
            }
            bufferedReader.close();

            jsonStr = stringBuilder.toString();
        } catch (IOException e) {
            log.error("文件解析失败", e);
            throw new BusinessException("001001", "文件解析失败");
        }
        return jsonStr;
    }


    public void exeScript(String py_path, String filepath, String result_dir) {
        String command = "python " + py_path +
                " --filepath " + filepath +
                " --outpath " + result_dir;
        //exe("conda activate e310");

        log.info("执行命令: " + command);
        exe(command);

    }

    public void exe(String command) {

        try {
            // 执行ls -l命令
            Process process = Runtime.getRuntime().exec(command);
            // 读取命令执行结果
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            // 等待命令执行完成
            process.waitFor();
            // 获取退出值
            int exitValue = process.exitValue();

            log.info("Exit value: " + exitValue);

            if (exitValue != 0) {
                log.error("执行解析命令失败");
                throw new BusinessException(ExceptionCodeEnum.PYTHON_ANALYSIS_ERROR.code, "执行解析命令失败");
            }
        } catch (Exception e) {
            log.error("执行解析命令失败");
            throw new BusinessException(ExceptionCodeEnum.PYTHON_ANALYSIS_ERROR.code, "执行解析命令失败");
        }

    }


    public void startModel(String submitTenderName) {
        String url = modeOnloadUrl;
        try {
            InputVO vo = new InputVO();
            vo.setFileName(submitTenderName);
            String param = JSONObject.toJSONString(vo);
            String post = HttpUtils.post(url, param);
            log.info("重新加载模型：" + post);
        } catch (Exception e) {
            log.error("模型加载失败", e);
            throw new BusinessException(ExceptionCodeEnum.MODE_LOAD_FAIL.code, "模型加载失败");
        }
    }

}

